Skip put() call fails without post-incremented key

This is odd, can't figure out what the issue is:

I have a function:

bool getModulesInFolder(Folder f, Skip &moduleSkip, int &moduleSkipIndex, bool recurse) 

Inside the function, I have a for loop to process each Item found in the folder. If the item is a formal module, I try to save it to the passed Skip list:

                        if (put(moduleSkip,moduleSkipIndex,modFullName))        
                        {
                                returnStatus=true
                                moduleSkipIndex++
                        }
                        else
                        {
                                //log error message...
                        }

The put() call only works for the first module, then fails for all subsequent put() calls!

However if I change the put() call to use an automatically post-incremented index, like this, all put() calls work and I get the expected full list of modules:

                        if (put(moduleSkip,moduleSkipIndex++,modFullName))
                        {
                                returnStatus=true
                        }
                        else
                        {
                            //put() did not work, restore the index
                            //(assumes even failed put() call will post-incremnt the index):
                                moduleSkipIndex--                               
                        }

Anyone know why the former format only works for the first put() call???


strathglass - Mon Jan 25 12:56:27 EST 2016

Re: Skip put() call fails without post-incremented key
TheNybbler - Mon Jan 25 16:54:19 EST 2016

I experienced a very similar problem recently, which took me ages to figure out what was happening.

The first version doesn't work because the variable you are using is a reference variable (int &moduleSkipIndex), so its using the address of the variable as the index in the skip list, rather than the int value being stored in the variable. This means that it works the first time through, but the second time through the loop, the put() call fails as the address of the variable was used as a key during the first time through the loop.

 

I'm not sure why the second version works, but it is probably to do with the way in which the DXL interpreter works.

 

Re: Skip put() call fails without post-incremented key
Mathias Mamsch - Tue Jan 26 04:30:04 EST 2016

TheNybbler - Mon Jan 25 16:54:19 EST 2016

I experienced a very similar problem recently, which took me ages to figure out what was happening.

The first version doesn't work because the variable you are using is a reference variable (int &moduleSkipIndex), so its using the address of the variable as the index in the skip list, rather than the int value being stored in the variable. This means that it works the first time through, but the second time through the loop, the put() call fails as the address of the variable was used as a key during the first time through the loop.

 

I'm not sure why the second version works, but it is probably to do with the way in which the DXL interpreter works.

 

The second variable obviously works, since the  int ::++(int &) perm returns the dereferenced integer variable, which is then put correctly to the skip list.

Generally references should only be used, if really necessary. So unless your function does not reallocate the skip list (which it should not do normally), you do not need to pass a reference. Skips can be modified from inside functions also if they are not passed as a reference.

I consider it good practice to only set the "output" variables of a function at the end of the function and not use them for "inner function processing". This avoids among other problems the very common reference in skip list problem. Regards, Mathias

Re: Skip put() call fails without post-incremented key
strathglass - Tue Jan 26 09:15:29 EST 2016

Thanks for the input guys - odd problem, but good to see it explained and understand the best way forward!